package com.can.lock;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;

/**
 * 自旋锁
 */
public class SpinlockDemo03 {

    //int 默认 0
    //Thread 默认 null
    AtomicReference<Thread> atomicReference = new AtomicReference<>();

    //加锁
    public void myLock(){
        Thread thread = Thread.currentThread();
        System.out.println(thread.getName()+"==> MyLock");
        //自旋锁
        //达到期望值就执行操作，第一次Thread默认为null执行操作变成thread
        //第二次判断期望值是否为Null 失败，因为第一次将值改为了thread
        while (!atomicReference.compareAndSet(null,thread)){
            System.out.println(Thread.currentThread().getName());
        }
    }

    //解锁
    public AtomicReference myUnLock(){
        Thread thread = Thread.currentThread();
        System.out.println(thread.getName()+"==> MyUnLock");
        atomicReference.compareAndSet(thread,null);
        return atomicReference;
    }
}

class TestSpinLock{
    public static void main(String[] args) throws InterruptedException {
//        ReentrantLock reentrantLock = new ReentrantLock();
//        reentrantLock.lock();
//        reentrantLock.unlock();

        //使用的自旋锁实现
        SpinlockDemo03 lock = new SpinlockDemo03();
        new Thread(()->{
            lock.myLock();
            try {
                TimeUnit.SECONDS.sleep(3);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.myUnLock();
            }
        },"T1").start();

        TimeUnit.SECONDS.sleep(1);

        //T2进入自旋锁,直到t1解锁，t2才解锁
        new Thread(()->{
            lock.myLock();
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                System.out.println(lock.myUnLock().get());
            }
        },"T2").start();

    }
}